package com.jing.yuntuku.service.impl;

import cn.hutool.core.io.FileUtil;
import com.jing.yuntuku.exception.BusinessException;
import com.jing.yuntuku.exception.ErrorCode;
import com.jing.yuntuku.service.OssPictureUploadTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

/**
 * OSS图片上传实现类：处理MultipartFile（本地文件）输入
 */
@Slf4j
public class MultipartFileOssUploader extends OssPictureUploadTemplate {

    // 允许的图片格式（与原有validPicture方法一致）
    private static final List<String> ALLOWED_PIC_FORMATS = Arrays.asList("jpeg", "jpg", "png", "webp");
    // 最大文件大小（2MB，与原有逻辑一致）
    private static final long MAX_PIC_SIZE = 2 * 1024 * 1024L;


    // -------------------------- 实现抽象类的差异化方法 --------------------------
    /**
     * 1. 验证输入源（MultipartFile）有效性
     */
    @Override
    protected void validPicture(Object inputSource) {
        // 1.1 验证输入源类型
        if (!(inputSource instanceof MultipartFile)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "输入源不是有效的文件类型");
        }
        MultipartFile file = (MultipartFile) inputSource;

        // 1.2 验证文件非空
        if (file.isEmpty() || file.getSize() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "上传文件不能为空");
        }

        // 1.3 验证文件大小
        if (file.getSize() > MAX_PIC_SIZE) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件大小不能超过2MB");
        }

        // 1.4 验证文件格式
        String originFilename = file.getOriginalFilename();
        String fileSuffix = FileUtil.getSuffix(originFilename).toLowerCase();
        if (!ALLOWED_PIC_FORMATS.contains(fileSuffix)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件类型错误，仅支持jpeg/jpg/png/webp");
        }
    }

    /**
     * 2. 提取原始文件名（从MultipartFile中获取）
     */
    @Override
    protected String getOriginFilename(Object inputSource) {
        MultipartFile file = (MultipartFile) inputSource;
        // 若原始文件名为空，用"unknown"兜底
        return StringUtils.hasText(file.getOriginalFilename()) ? file.getOriginalFilename() : "unknown_pic";
    }

    /**
     * 3. 处理文件（将MultipartFile写入临时文件）
     */
    @Override
    protected void processFile(Object inputSource, File tempFile) throws IOException {
        MultipartFile file = (MultipartFile) inputSource;
        // 用缓冲流将MultipartFile的输入流写入临时文件
        try (InputStream in = file.getInputStream();
             FileOutputStream out = new FileOutputStream(tempFile)) {

            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            log.error("MultipartFile写入临时文件失败，临时路径：{}", tempFile.getAbsolutePath(), e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "文件处理失败");
        }
    }
}